/*
 * Copyright 2003-2005 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

#include "../Types.h"

#include "U16ArrayByte.h"

#include "BigEndianUnsignedShort.h"

type_name u16binary_name = { "u16binary" };

int u16binary_read( type_input_stream * in, type_element * element, void * privateData )
{
	uint16_t length;
	uint8_t * data;
	
	int toRead = 0;
	int haveRead = 0;
	int read = 0;
	u16array * ret;

	/*The below line won't work because we don't know what U8BID
	//is registered as in the remote system.
	//Byte id = (Byte) in.readObject( TypeMapCore.U8BID );
	//We can either use the element to find the reference object
	//in the sequence definition or cheat and just read a byte.
	//cout << "bytearray read" << endl;
	//unsigned int * length = (unsigned int *) in.readObject( (char*) BigEndianUnsignedInteger::TYPENAME );
	 */
	type_input_read_named_object(in, &uint16_name );
	
	length = type_stack_get_u16( type_input_stack(in) );
	data = (uint8_t *) type_malloc( length );
	
	toRead = length;
	haveRead = 0;
	read = 0;
	
	while( toRead > 0 )
	{
		if ( haveRead > 0 )
		{
			if ( read==0 )
			{
			   type_input_set_error(in, 10 );
			   return TYPE_EOF;
			}
		}

		read = type_input_read_buffer(in, (char *) data+haveRead, toRead );
		
		toRead = toRead - read;
		haveRead += read;
	}
	
	ret = (u16array *) type_malloc( sizeof( u16array ) );
	ret->size = length;
	ret->data = data;
		
	type_stack_set_ptr( &in->stack, element, ret );
	return TYPE_OK;
}

/* (non-Javadoc)
 * @see com.live.colony.type.TypeWriter#write(com.live.colony.type.TypeMimeOutputStream, java.lang.Object)
 */
int u16binary_write( type_output_stream * out, void * o, type_element * element, void * data )
{	
	u16array * array = (u16array *) o;
	uint32_t size = (unsigned int) array->size;

	type_output_write_named_object( out, &uint16_name, &size );

	type_output_write_buffer( out, (char *) array->data, array->size );
	return TYPE_OK;

}




